package com.kun.video.controller;

import com.kun.video.context.impl.StageSingletonContext;
import com.kun.video.domain.StageSize;
import com.kun.video.exception.Assert;
import com.kun.video.util.ComUtil;
import com.kun.video.util.CssManager;
import javafx.scene.Scene;
import javafx.scene.layout.Region;
import javafx.stage.Stage;
import javafx.stage.Window;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 抽象控制器基类，提供视图控制的基础结构和生命周期管理
 *
 * <p>子类需实现响应式布局方法和舞台尺寸配置</p>
 *
 * @author gzc
 * @since 2024/9/22
 */
public abstract class AbstractController {
    /**
     * 使用具体子类的类名作为日志标识
     */
    protected final Logger log = LoggerFactory.getLogger(this.getClass());
    protected Stage stage;
    protected Scene scene;
    protected Region rootNode;
    protected CssManager.Theme theme;
    protected volatile boolean isInitialized = false;

    protected StageSize stageSize;

    /**
     * 初始化控制器基础配置
     *
     * @param rootNode 根布局节点
     * @param isStage  是否创建独立舞台（true时创建新Stage，false时复用已有Window）
     */
    public void init(Region rootNode, boolean isStage) {
        this.rootNode = rootNode;
        initializeScene();
        initializeStage(isStage);
        configureStageDimensions();
        setDefaultTheme();
    }

    /**
     * 设置默认主题
     */
    protected void setDefaultTheme() {
        CssManager.getInstance().applyTheme(rootNode, CssManager.DEFAULT_THEME.getThemeName());
    }

    /**
     * 初始化场景对象
     */
    private void initializeScene() {
        if (rootNode != null && rootNode.getScene() == null) {
            scene = new Scene(rootNode);
        }
    }

    /**
     * 初始化舞台配置
     */
    private void initializeStage(boolean isStage) {
        if (!isStage) {
            return;
        }

        Window window = scene.getWindow();
        if (window == null) {
            stage = new Stage();
            stage.setScene(scene);
        } else {
            stage = (Stage) window;
        }
    }

    /**
     * 配置舞台尺寸约束
     */
    private void configureStageDimensions() {
        stageSize = getMainStageSize();
        if (stage == null || stageSize == null) {
            return;
        }
        stage.setWidth(stageSize.getPrefWidth());
        stage.setHeight(stageSize.getPrefHeight());
        stage.setMinWidth(stageSize.getMinWidth());
        stage.setMinHeight(stageSize.getMinHeight());
        stage.setMaxWidth(stageSize.getMaxWidth());
        stage.setMaxHeight(stageSize.getMaxHeight());
    }

    /* -------------------------- 抽象方法区域 ------------------------------ */

    /**
     * 获取主舞台尺寸配置（需子类实现）
     *
     * @return 窗口尺寸
     */
    protected abstract StageSize getMainStageSize();

    /**
     * 响应式宽度调整逻辑（需子类实现）
     *
     * @param width  主容器当前宽度
     * @param height 主容器当前高度
     */
    protected abstract void reactiveDimensions(Double width, Double height);

    /* ----------------------------- 生命周期方法 --------------------------- */

    /**
     * 执行UI初始化流程（自动在JavaFX线程执行）
     */
    public void runBeforeCallback() {
        if (isInitialized) {
            return;
        }
        ComUtil.uiThreadRun(this::executeLifecycle);
    }

    /**
     * 完整的生命周期执行流程
     */
    private void executeLifecycle() {
        // 布局前准备
        initLayoutBefore();
        // 核心布局初始化
        initLayout();
        // 响应式配置
        setupResponsive();
        // 事件监听注册
        registerMonitor();
        // 数据初始化流程
        initDataBefore();
        initData();
        initDataAfter();
        // 设置默认主题
        setDefaultTheme();
        isInitialized = true;
    }

    /**
     * 配置响应式布局监听器
     */
    private void setupResponsive() {
        // 初始赋值
        reactiveDimensions(stageSize.getPrefWidth(), stageSize.getPrefHeight());
        // 监听窗口高度宽度变化
        stage.widthProperty().addListener((obs, ov, nv) -> reactiveDimensions(nv.doubleValue(), null));
        stage.heightProperty().addListener((obs, ov, nv) -> reactiveDimensions(null, nv.doubleValue()));
    }

    /**
     * 展示窗口（线程安全）
     */
    public void show() {
        ComUtil.uiThreadRun(() -> {
            if (!stage.isShowing()) {
                stage.show();
            }
            setupCloseHandler();
        });
    }

    /**
     * 配置窗口关闭处理器
     */
    private void setupCloseHandler() {
        stage.setOnCloseRequest(event -> {
            StageSingletonContext.removeInstance(this.getClass());
            // 阻止默认关闭行为
            event.consume();
            // 显式执行关闭
            stage.close();
        });
    }

    /* --------------------基础模板方法（供子类按需重写）--------------------- */
    protected void initLayoutBefore() {
        // 布局前操作（如加载样式表）
    }

    protected void initLayout() {
        // 核心布局逻辑
    }

    protected void registerMonitor() {
        // 事件监听注册
    }

    protected void initData() {
        // 数据初始化
    }

    protected void initDataBefore() {
        // 数据初始化前操作
    }

    protected void initDataAfter() {
        // 数据初始化后操作
    }

    public void stopCallback() {
        // 关闭时的清理操作
    }

    public void applyTheme(CssManager.Theme theme) {
        Assert.notNull(theme, "主题为空");
        CssManager.getInstance().applyTheme(rootNode, theme.getName());
    }

    public void applyTheme(String themeName) {
        Assert.notBlank(themeName, "主题为空");
        CssManager.getInstance().applyTheme(rootNode, themeName);
    }


    public Stage getStage() {
        return stage;
    }

    public Scene getScene() {
        return scene;
    }

    public Region getRootNode() {
        return rootNode;
    }
}